package preprocessing;

import java.util.List;

import data.MatrixTime;


public class Normalizer {
	public static void space_normalize(List<MatrixTime> ets) {
		for(MatrixTime et: ets) {
			double[][] mat = et.getMat();
			
			// compute spatial mean
			double mean = 0;
			double tot = 0;
			for(int i=0; i<mat.length;i++) 
				for(int j=0; j<mat[i].length;j++) {
					if(mat[i][j] >= 0) {
						mean += mat[i][j];
						tot ++;
					}
				}
			
			mean = mean / tot;
			
			// normalize
			for(int i=0; i<mat.length;i++) 
			for(int j=0; j<mat[i].length;j++) 
				if(mat[i][j] > 0) 
					et.getMat()[i][j] = mat[i][j] / mean;
		}
	}
	
	
	
	public static void local_space_normalize(List<MatrixTime> ets) {
		for(MatrixTime et: ets) {
			double[][] mat = et.getMat();
			
			int k = 1;
			// normalize
			for(int i=k; i<mat.length-k;i++) 
			for(int j=k; j<mat[i].length-k;j++) 
				if(mat[i][j] > 0) {
					
					// compute local spatial mean
					double mean = 0;
					double tot = 0;
					for(int ii=i-k; ii<=i+k;ii++) 
						for(int jj=j-k; jj<=j+k;jj++) {
							if(mat[ii][jj] >= 0) {
								mean += mat[ii][jj];
								tot ++;
							}
					}
					mean = mean / tot;
					
					
					
					et.getMat()[i][j] = mat[i][j] / mean;
				}
			
			
			
			
		}
	}
	
	
	
	
	public static void time_normalize(List<MatrixTime> ets, double[][] mean) {
		for(int i=0; i<ets.get(0).getMat().length;i++) 
		for(int j=0; j<ets.get(0).getMat()[i].length;j++) {	
			if(mean[i][j] != 0) {
				for(int t=0; t<ets.size();t++)
					if(ets.get(t).getMat()[i][j] > 0)
					ets.get(t).getMat()[i][j] = ets.get(t).getMat()[i][j] / mean[i][j];	
			}
		}
	}
	
	
	public static void pfipf_normalize(List<MatrixTime> ipf, List<MatrixTime> pf) {
		for(int i=0; i<ipf.get(0).getMat().length;i++) 
		for(int j=0; j<ipf.get(0).getMat()[i].length;j++) {
			for(int t=0; t<ipf.size();t++)
				if(pf.get(t).getMat()[i][j]>0)
					ipf.get(t).getMat()[i][j] = ipf.get(t).getMat()[i][j]*pf.get(t).getMat()[i][j];	
			
		}
	}
	
	
	public static void normalize01(List<MatrixTime> ets) {	
		double max = ets.get(0).getMat()[0][0];
		double min = ets.get(0).getMat()[0][0];
		
		for(MatrixTime et: ets) {
			double[][] mat = et.getMat();
			for(int i=0; i<mat.length;i++) 
			for(int j=0; j<mat[i].length;j++) {
				if(mat[i][j] != -1) {
					max = Math.max(max, mat[i][j]);
					/*
					if(mat[i][j]>100) 
						System.out.println("***** "+mat[i][j]+" @ "+i+","+j);
					*/
					/*
					if(i==14 && j==3)
						System.out.println("***** "+mat[i][j]+" @ "+i+","+j);
					*/
					
					min = Math.min(min, mat[i][j]);
				}
			}
		}
		
		System.out.println("MAX = "+max);
		System.out.println("MIN = "+min);
		
		for(MatrixTime et: ets) {
			double[][] mat = et.getMat();
			for(int i=0; i<mat.length;i++) 
			for(int j=0; j<mat[i].length;j++)
				if(mat[i][j] > 0)
					mat[i][j] = (mat[i][j] - min)/(max - min);
		}
	}
	
	public static void normalize01(MatrixTime et) {	
		double max = et.getMat()[0][0];
		double min = et.getMat()[0][0];
		
		
		double[][] mat = et.getMat();
		for(int i=0; i<mat.length;i++) 
			for(int j=0; j<mat[i].length;j++){
				if(mat[i][j] != -1) {
					max = Math.max(max, mat[i][j]);
					min = Math.min(min, mat[i][j]);
				}
			}
		
		
		System.out.println("MAX = "+max);
		System.out.println("MIN = "+min);
		
		
		
		for(int i=0; i<mat.length;i++) 
		for(int j=0; j<mat[i].length;j++)
			if(mat[i][j] > 0)
				mat[i][j] = (mat[i][j] - min)/(max - min);
		
	}
}
